﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DDD.Core;

using FloatComparer = DDDTest.Helper.FloatComparer;


namespace DDDTest.Core {
    [TestClass]
    public class TestMorphMesh {
        [TestMethod]
        public void Test_New1 () {
            var msh = new MorphMesh (4);
            var expected = new float[] { 0, 0, 0, 0 };

            Assert.AreEqual (4, msh.MorphTargetCount);
            CollectionAssert.AreEqual (expected, msh.MorphWeights);
        }

        [TestMethod]
        public void Test_New2 () {
            var msh = new MorphMesh (2, 4);
            var expected = new float[] { 0, 0, 0, 0 };

            Assert.AreEqual (2, msh.SubmeshCount);
            Assert.AreEqual (4, msh.MorphTargetCount);
            CollectionAssert.AreEqual (expected, msh.MorphWeights);
        }

        [TestMethod]
        public void Test_SetBaseTarget () {
            var msh = new MorphMesh (2, 4);
            var vbuf = new VertexBuffer ();

            msh.SetBaseTarget (vbuf);

            Assert.AreEqual (vbuf, msh.BaseTarget);
        }

        [TestMethod]
        public void Test_SetMorphTarget () {
            var msh = new MorphMesh (4);
            var vbuf1 = new VertexBuffer ();
            var vbuf2 = new VertexBuffer ();

            msh.SetMorphTarget (0, vbuf1);
            msh.SetMorphTarget (1, vbuf2);

            Assert.AreEqual (vbuf1, msh.GetMorphTarget (0));
            Assert.AreEqual (vbuf2, msh.GetMorphTarget (1));
        }

        [TestMethod]
        public void Test_SetMorphWeight () {
            var msh = new MorphMesh (4);

            msh.SetMorphWeight (0, 1.0f);
            msh.SetMorphWeight (1, 2.0f);

            var expected = new float[] { 1, 2, 0, 0 };

            Assert.AreEqual (1.0f, msh.GetMorphWeight (0));
            Assert.AreEqual (2.0f, msh.GetMorphWeight (1));
            CollectionAssert.AreEqual (expected, msh.MorphWeights);
        }

        [TestMethod]
        public void Test_SetMorphWeights () {
            var msh = new MorphMesh (4);
            msh.SetMorphWeights (new float[] { 1, 2, 3, 4 });

            var expected = new float[] { 1, 2, 3, 4 };

            Assert.AreEqual (1.0f, msh.GetMorphWeight (0));
            Assert.AreEqual (2.0f, msh.GetMorphWeight (1));
            Assert.AreEqual (3.0f, msh.GetMorphWeight (2));
            Assert.AreEqual (4.0f, msh.GetMorphWeight (3));

            CollectionAssert.AreEqual (expected, msh.MorphWeights);
        }

        [TestMethod]
        public void Test_MorphTarget_Enumerator () {
            var msh = new MorphMesh (4);

            var sum = msh.MorphTargets.Sum (x => 1);

            Assert.AreEqual (4, sum);
        }

        [TestMethod]
        public void Test_References () {
            var msh = new MorphMesh (4);
            var vbuf1 = new VertexBuffer ();
            var vbuf2 = new VertexBuffer ();
            var vbuf3 = new VertexBuffer ();
            msh.SetBaseTarget (vbuf1);
            msh.SetMorphTarget (0, vbuf2);
            msh.SetMorphTarget (1, vbuf3);

            var objs = msh.References;

            Assert.AreEqual (3, objs.Count ());
            Assert.AreEqual (true, objs.All (x => x != null));
        }

        [TestMethod]
        public void Test_Find () {
            var vbuf1 = new VertexBuffer ();
            var vbuf2 = new VertexBuffer ();
            var vbuf3 = new VertexBuffer ();
            var msh = new MorphMesh (4);
            msh.SetBaseTarget (vbuf1);
            msh.SetMorphTarget (0, vbuf2);
            msh.SetMorphTarget (1, vbuf3);

            vbuf1.UserID = 101;
            vbuf2.UserID = 102;
            vbuf3.UserID = 103;
            msh.UserID = 104;

            Assert.AreEqual (vbuf1, msh.Find (101));
            Assert.AreEqual (vbuf2, msh.Find (102));
            Assert.AreEqual (vbuf3, msh.Find (103));
            Assert.AreEqual (msh, msh.Find (104));
        }
    }
}
